/*
 *
 * Copyright (c) 2011 by Steve Devore
 *                       http://bookscanwizard.sourceforge.net
 *
 * This file is part of the Book Scan Wizard.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package net.sourceforge.bookscanwizard;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

public class ConfigEntry extends JTextArea  {
    private ActionListener menuHandler;
    private JMenuItem popupItemBarcode;
    private JMenuItem popupItemPoints;

    public ConfigEntry(ActionListener handler) {
        super("", 10, 80);
        menuHandler = handler;

        final JPopupMenu popup = new JPopupMenu() {
            @Override
            public void show(Component invoker, int x, int y) {
                boolean barcode = getCurrentLineOrSelection().contains("Barcodes");
                popupItemBarcode.setVisible(barcode);
                popupItemPoints.setVisible(!barcode);
                super.show(invoker, x, y);
            }
        };
        popupItemPoints = new JMenuItem("Copy points to viewer");
        popupItemPoints.setActionCommand("copy_points_to_viewer");
        popupItemPoints.addActionListener(menuHandler);
        popup.add(popupItemPoints);

        popupItemBarcode = new JMenuItem("Expand Barcode Operations");
        popupItemBarcode.setActionCommand("expand_barcode_operations");
        popupItemBarcode.addActionListener(menuHandler);
        popup.add(popupItemBarcode);

        MouseListener popupListener = new PopupListener(popup);
        addMouseListener(popupListener);

        final UndoManager undo = new UndoManager();
        Document doc = getDocument();
        // Listen for undo and redo events
        doc.addUndoableEditListener(new UndoableEditListener() {
            @Override
            public void undoableEditHappened(UndoableEditEvent evt) {
                undo.addEdit(evt.getEdit());
            }
        });

        // Create an undo action and add it to the text component
        getActionMap().put("undo", new AbstractAction("undo") {
            @Override
            public void actionPerformed(ActionEvent evt) {
                try {
                    if (undo.canUndo()) {
                        undo.undo();
                    }
                } catch (CannotUndoException e) {
                }
            }
        });
        // Create a redo action and add it to the text component
        getActionMap().put("redo", new AbstractAction("redo") {
            @Override
            public void actionPerformed(ActionEvent evt) {
                try {
                    if (undo.canRedo()) {
                        undo.redo();
                    }
                } catch (CannotRedoException e) {
                }
            }
        });
    }

    public void insertCommand(OpDefinition def)  {
        try {
            getDocument().insertString(getCaretPosition(), def.getExample(), null);
        } catch (BadLocationException ex) {
            Logger.getLogger(ConfigEntry.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getConfigToPreview() {
        if (!BSW.instance().getMainFrame().isPreviewToCursor()) {
            return getText();
        } else {
            int pos = Math.max(0, getCaret().getDot() - 1);
            String txt = getText().substring(0, pos);
            int endLine = getText().indexOf("\n", pos);
            if (endLine >0) {
                txt = txt + getText().substring(pos, endLine);
            }
            return txt;
        }
    }
    
    public String getCurrentLineOrSelection() {
        String text = getText();
        int dot = getCaret().getDot();
        int mark = getCaret().getMark();
        if (dot == mark) {
            int endLine = text.indexOf("\n", dot);
            if (endLine < 0) {
                endLine = text.length();
            }
            int startLine = text.lastIndexOf("\n", dot-1);
            if (startLine < 0) {
                startLine = 0;
            }
            return text.substring(startLine, endLine);
        } else {
            return text.substring(Math.min(dot, mark), Math.max(dot, mark));
        }
    }
}
